
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>


/*
* lba file's format:
*    /path/to/file: 100(2), 500(5), 10000(10)
*   ...
*/

/* File Mapping Extent */
struct FileBMapExtent{
	unsigned long long offset, length;
	struct FileBMapExtent *next;
};

/* Infomation of File Block Mapping  */
struct FileBMap {
	char filename[256];
	struct FileBMapExtent *extent_head, *extent_tail;
};


struct FileBMap * FileBMap_create(char *filename)
{
	assert(filename!=NULL);
	assert(strlen(filename)<255);
	struct FileBMap *p = (struct FileBMap *)malloc(sizeof(struct FileBMap));
	assert(p!=NULL);
	p->extent_head=NULL;
	p->extent_tail=NULL;
	strcpy(p->filename, filename);
	return p;
}

void FileBMap_destroy(struct FileBMap *p)
{
	assert(p!=NULL);
	while(p->extent_head){
		struct FileBMapExtent *e = p->extent_head;
		p->extent_head = e->next;
		free(e);
	}
	free(p);
}

void FileBMap_appendExtent(struct FileBMap *p, unsigned long long offset, unsigned long long length)
{
	assert(p!=NULL);
	struct FileBMapExtent *e = (struct FileBMapExtent *)malloc(sizeof(struct FileBMapExtent));
	assert(e!=NULL);
	e->offset = offset;
	e->length = length;
	e->next = NULL;
	
	//add the extent to the FileBmap:
	if(p->extent_tail==NULL){
		p->extent_head = e;
	}else{
		p->extent_tail->next = e;
	}
	p->extent_tail = e;
}

void FileBMap_show(struct FileBMap *p)
{
	struct FileBMapExtent *t;
	assert(p!=NULL);
	printf("%s ->", p->filename);
	for(t=p->extent_head;t!=NULL; t=t->next){
		printf(" %llu(+%llu)", t->offset, t->length);
	}
	printf("\n");
}
void make_line()
{}

void parse_line0(char *line)
{
	char *extent;
	printf("%s ->", strtok(line, ":"));
	while(extent=strtok(NULL, ", ")){
		int offset, length;
		sscanf(extent, "%d(%d)", &offset, &length);
		printf(" %d(+%d)", offset, length);
	}
	printf("\n");
}
void parse_line(char *line)
{
	struct FileBMap *p;
	char *extent;
	p = FileBMap_create(strtok(line, ":"));
	while(extent=strtok(NULL, ", ")){
		int offset, length;
		sscanf(extent, "%d(%d)", &offset, &length);
		FileBMap_appendExtent(p, offset, length);
	}
	FileBMap_show(p);
	FileBMap_destroy(p);
}

#define LBA_FILE "lba.txt"
#define MAX_LINE 4000
int read_file(char *filename)
{
	char buffer[4096];
	FILE *fp;
	if(!(fp=fopen(filename, "r"))){
		fprintf(stderr, "Error: cann't open file '%s'\n", filename);
		return -1;
	}
	printf("Reading from file '%s'\n", filename);
	// reading line by line:
	while(fgets(buffer, MAX_LINE, fp)){
		printf("%s", buffer);
		parse_line(buffer);
	}
	fclose(fp);
	return 0;
}

int main(int argc, char *argv[])
{
	read_file(LBA_FILE);
	return 0;
}
